#pragma once
#include <lcir/Utils/Utils.h>

#include <cstddef>
#include <tuple>
namespace lcir {
/// TODO: 给SlotTys加个类型校验
template <class... SlotTys>
class SlotCombiner {
  using tup = std::tuple<SlotTys...>;
  using combinerTy = SlotCombiner<SlotTys...>;
  std::tuple<SlotTys...> slots;
  static constexpr size_t slotNums = std::tuple_size_v<tup>;
  template <class SlotTy>
  constexpr static size_t getSlotTyIdx() {
    return getTupleElementIdx<tup, SlotTy>();
  }

 public:
  template <class SlotTy>
  bool hasSlot() {
    return combinerTy::getSlotTyIdx<SlotTy>() < slotNums;
  }
  template <class SlotTy>
  SlotTy* getSlot() {
    constexpr size_t idx = combinerTy::getSlotTyIdx<SlotTy>();
    if constexpr(idx >= slotNums)
      return nullptr;
    else {
      return &std::get<idx>(slots);
    }
  }
};
}  // namespace lcir